package cbbx_sm.simulation;

import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;

import cbbx_sm.decision_maker.search.DynamicProgrammingLookahead;
import cbbx_sm.decision_maker.search.DynamicProgrammingTableEntry;
import cbbx_sm.decision_maker.search.States;
import cbbx_sm.evaluation.CompareAlternativeSchedulers.Decision;
import cbbx_sm.probabilistic_model.Cluster;
import cbbx_sm.probabilistic_model.ProbabilisticModel;
import cbbx_sm.utils.LookaheadPredictorSerializator;
import edu.uci.ics.jung.graph.util.Pair;


public class GenerateLookaheadTableSizeGraph {

	public static void main(String[] args) throws NumberFormatException,
			Exception {
	  LookaheadPredictorSerializator.lookaheadFolder = //"/Users/ronenwai/Documents/output/";
	      "/Users/ronenwai/Desktop/";
	  //DynamicProgrammingLookahead.TIMEOUT = 2*60*1000; // One Minute;
		// String testDay = "20090526-short";
		String testDay = "20090528";
		// String testDay = "20090527";
		// DO NOT CHANGE
		String trainDay = "20090527";
		// Cameras scheduled.
		ArrayList<String> cameraIds = new ArrayList<String>();
		cameraIds.add("cam13");
		cameraIds.add("cam14");
		cameraIds.add("cam15");
		cameraIds.add("cam16");
		cameraIds.add("cam17");
		cameraIds.add("cam18");
		double utilityZoom = 1;
		double utilityUP = 0;
		List<String> results = new ArrayList<String>();
		for (float delta = 0.4f; delta >= 0.1f; delta -= 0.1f) {
			int clusters = 4;
			utilityUP = 0;
			//for (; utilityUP <= 1; utilityUP += 0.1) {
				// Lookahead = future
				performEvauation(cameraIds, clusters, Decision.lookahead,
						utilityZoom, utilityUP, delta, 10, testDay,
						trainDay, results);
			//}
		}
		System.out.println("Cam" +"\t" + "utilityZoom" + "\t" + "utilityUP" + "\t" + "delta" + "\t" + "camTable.length" + "\t" + 
	        "camTable[0].length" +"\t" + "generationTime" + "\t" + "sizes.fst" + "\t" + "sizes.snd" + "\t" + "DynamicProgrammingLookahead.lastCallPrematureTermination");
		for (String s :  results) {
		  System.out.println(s);
		}
		System.out.println("Done with all!");
	}

	public static void performEvauation(ArrayList<String> cameraIds,
			int numClusters, Decision decision, double utilityZoom,
			double utilityUP, double delta, int numberOfTimeStampsLookAhead,
			String testDay, String trainDay, List<String> results) throws NumberFormatException,
			Exception {

		boolean regenerate = true;
		// Load the probabilistic model or create it.
		String camerasConcat = "";
		int i = 0;
		for (String cam : cameraIds) {
			camerasConcat += cam + (i < (cameraIds.size() - 1) ? "_" : "");
			i++;
		}
		String modelFileName = "model" + camerasConcat + "_" + "k="
				+ numClusters + "_kmeans.ser";
		for (String cam : cameraIds) {
			
			// Load model to figure out which index was each cluster when single
			// camera model was created.
			ProbabilisticModel probModel = ProbabilisticModel.readUp(modelFileName);
			ProbabilisticModel singleCamModel = probModel.projectModel(cam);
			if (regenerate){
				LookaheadPredictorSerializator.deletePrevious(
						singleCamModel, utilityZoom, utilityUP,
						numberOfTimeStampsLookAhead, delta);
			}
			DynamicProgrammingLookahead camTable =
				LookaheadPredictorSerializator.readUpScoreArray(
						singleCamModel, utilityZoom, utilityUP, delta,
						numberOfTimeStampsLookAhead);

			ArrayList<double[]> rawStates = null;
			States camStates = null;
			Hashtable<Cluster, Integer> clusterIndex = null;
			Long generationTime = null;
			long timeBeforeCall = System.currentTimeMillis();
			if (camTable == null) {
				LookaheadPredictorSerializator.generateLookaheadTable(
						singleCamModel, utilityZoom, utilityUP,
						numberOfTimeStampsLookAhead, delta);
				generationTime = System.currentTimeMillis() - timeBeforeCall;
				rawStates = camTable.getStates();
			}
			camTable = LookaheadPredictorSerializator.readUpScoreArray(
					singleCamModel, utilityZoom, utilityUP, delta,
					numberOfTimeStampsLookAhead);
			rawStates = camTable.getStates();
			camStates = new States(rawStates, singleCamModel);
			Pair<Long> sizes = LookaheadPredictorSerializator.getSize(
                singleCamModel, utilityZoom, utilityUP,
                numberOfTimeStampsLookAhead, delta);
			String outputLine = cam + "\t" + utilityZoom + "\t" + utilityUP + "\t" + delta + "\t" + 
                rawStates.size() +"\t" + generationTime + "\t" + sizes.getFirst() + "\t" + 
                sizes.getSecond() + "\t" + DynamicProgrammingLookahead.lastCallPrematureTermination;
			System.out.println(outputLine);
			results.add(outputLine);
		}
	}
}
